/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package weka.attributeSelection.semiAS.semiClusterAS;

import weka.core.Instances;

/**
 *
 * @author Administrator
 */
public class DistEvalM implements Distance {

    private UnlabeledDistEvalM m_unlabledDistEvalM;
    private LabeledDistEvalM m_labledDistEvalM;
    private boolean m_isWeighted;
    private Mode m_modeAS;
    private double m_LabeledWeight;
    private double m_UnlabledWeight;
    private Instances m_instances;
    private Instances m_labeledInstances;
    private Instances[] m_data;

    public DistEvalM(final Instances data, final Instances lData, final Instances[] classData, boolean b, Mode s, double l, double u, LabeledDistMethod lOption, UnlabeledDistMethod uOption) {
        m_instances = data;
        m_labeledInstances = lData;
        m_data = classData;
        m_isWeighted = b;
        m_modeAS = s;
        m_LabeledWeight = l;
        m_UnlabledWeight = u;

        switch (m_modeAS) {
            case LabeledAS:
                m_unlabledDistEvalM = new UnlabeledDistEvalM(uOption, m_labeledInstances);
                break;

            case SemiAS:
                m_unlabledDistEvalM = new UnlabeledDistEvalM(uOption, m_instances);
                break;

            default:
                m_unlabledDistEvalM = new UnlabeledDistEvalM(uOption, m_instances);
                break;
        }

        if (m_isWeighted) {
            if (m_LabeledWeight != 0) {
                m_labledDistEvalM = new LabeledDistEvalM(lOption, m_labeledInstances, m_data);
            }
        }
    }

    public double getDistance(int i, int j) {
        double labelDistance = 0.0;
        double unlabelDistance = 0.0;

        if (m_UnlabledWeight != 0) {
            unlabelDistance = m_unlabledDistEvalM.getDistance(i, j);
//            if (unlabelDistance > 1 || unlabelDistance < 0 || unlabelDistance == Double.NaN) {
//                System.out.println("unlabelDistance=" + unlabelDistance);
//            }
        }
        if (m_isWeighted) {
            if (m_LabeledWeight != 0) {
                labelDistance = m_labledDistEvalM.getDistance(i, j);
            }
            return m_UnlabledWeight * unlabelDistance + m_LabeledWeight * labelDistance;
        } else {
            return unlabelDistance;
        }
    }
}
